#include "savage.h"
#include "Scene.h"
#include "ThorSceneManager.h"
#include "pig.h"

#include "OgreMaterialManager.h"

void Savage::update(Ogre::Real timeSinceLast)
{
	//get pig node name first;
	Ogre::String _pigName = Ogre::String("pig1");
	//get pig node
	Ogre::Node * _pig = ThorSceneManager::getInstance()->getCurrentScene()->getNPCSprite(_pigName)
		->getSpriteNode();

	switch(mState)
	{
	case  CLUB_ATTACKING:
		{
			//if attack succeeds
			//get the distance between attack point and pig's position
			Ogre::Quaternion _quat= getOrientation();

			Ogre::Vector3 v3 = attackTagPoint_club_rel;
			v3 = _quat*v3;
			v3 += getSpriteNode()->getPosition() - mCenterOffset;


			Ogre::Vector3 attackSphere_center = v3; 
			Ogre::Sphere attackSphere(attackSphere_center,Ogre::Real(0.25f));
			//get aabb of the pig
			Sprite * _sprite = ThorSceneManager::getInstance()->getCurrentScene()->getNPCSprite("pig1");

			Ogre::AxisAlignedBox pigAABB = _sprite->getEntity()->getBoundingBox();
			pigAABB.transform(_pig->_getFullTransform());

			//get beat direction
			Ogre::Vector3 beat_direction(-1.f,2.f,1.f);
			beat_direction = ( _quat * beat_direction).normalisedCopy() * attack_power_factor; 

			if (pigAABB.intersects(attackSphere))
			{
				Ogre::Real currentMotionTime = m_pAnimationMixState->getCurrentDestAS()->getTimePosition();
				if(currentMotionTime >= 0.40f &&currentMotionTime <= 0.45f)
				{
					//Hit!!!!
					((Pig*)_sprite)->beaten(beat_direction);
					mState = ATTACKING_SUCCESS;
				}

			}
			if(m_pAnimationMixState->getCurrentDestAS()->getAnimationName() == "attack01")
			{
				Ogre::Real currentMotionTime = m_pAnimationMixState->getCurrentDestAS()->getTimePosition();
				if(currentMotionTime == m_pAnimationMixState->getCurrentDestAS()->getLength())
				{
					mState = ATTACKING_MISS;
				}
			}

		}
		break;
	case ATTACKING_MISS:
		{
			if (m_pAnimationMixState->getCurrentDestAS()->getAnimationName() == "rest")
			{
				//Ogre::Real currentMotionTime = m_pAnimationMixState->getCurrentDestAS()->getTimePosition();
				if(m_pAnimationMixState->hasPlayedOnce() &&m_pAnimationMixState->getLoopTime()>=4)
				{
					mState = STANDING;
				}
			}

		}
		break;
	case ATTACKING_SUCCESS:
		{
			if (m_pAnimationMixState->getCurrentDestAS()->getAnimationName() == "cheer01")
			{
				//Ogre::Real currentMotionTime = m_pAnimationMixState->getCurrentDestAS()->getTimePosition();
				if(m_pAnimationMixState->hasPlayedOnce() &&m_pAnimationMixState->getLoopTime()>=2)
				{
					mState = STANDING;
				}
			}

		}
		break;
	case SHOCKED_BY_LIGHTNING:
		{
			shockTime_process -= timeSinceLast;
			if (shockTime_process <= 0)
			{
				mState = STANDING;
				reserved_TextureUnitState->setTextureName(originalTexture_name);
			}
		}
		break;
	default:  // free to chase
		{
			//get pig position	
			mDestination = _pig->getPosition();
			//TODO: && the angle between the orientation and the distance vector should be less
			//than a certain value.
			if ((mPosition - mDestination).squaredLength() < attackRange2)
			{
				mDestination = mPosition + (mDestination - mPosition).normalisedCopy();
				mState = CLUB_ATTACKING;
			}
			
			//get orientation
			mAngularDestination = 
				-(mPosition - mDestination);

			//move acoording to the destination we have gotten.
			Sprite::update(timeSinceLast);


			//overide super's motion judgement and re-validate
			//if close to pig, and the distance is less than attack range
			//then trigger attack motion
			//TODO: && the angle between the orientation and the distance vector should be less
			//than a certain value.
			if ((mPosition - mDestination).squaredLength() < attackRange2)
			{
				mState = CLUB_ATTACKING;	
			}
		}
		break;
	}
	


	animationChanging(timeSinceLast);



}

void Savage::animationChanging(Ogre::Real timeSinceLast)
{

	//for addTime
	Sprite::animationChanging(timeSinceLast);

	

	////////////////////////---------------------animation changing
	if((mState & STANDING) != 0)
	{
		Ogre::String currentAS = m_pAnimationMixState->getCurrentDestAS()->getAnimationName();
		if(currentAS == "stand01")
			return;
		Ogre::String name("stand01");
		m_pAnimationMixState->changeAnimation(name);
	}
	else if((mState & STRAIGHT_RUNING) != 0)
	{
		Ogre::String currentAS = m_pAnimationMixState->getCurrentDestAS()->getAnimationName();
		if(currentAS == "run02")
			return;
		Ogre::String name("run02");
		m_pAnimationMixState->changeAnimation(name);
	}
	else if((mState & TURNING) != 0)
	{
		Ogre::String currentAS = m_pAnimationMixState->getCurrentDestAS()->getAnimationName();
		if(currentAS == "run02")
			return;
		Ogre::String name("run02");
		m_pAnimationMixState->changeAnimation(name);
	}
	else if ((mState & CLUB_ATTACKING) != 0)
	{
		Ogre::String currentAS = m_pAnimationMixState->getCurrentDestAS()->getAnimationName();
		if(currentAS == "attack01")
			return;
		Ogre::String name("attack01");
		m_pAnimationMixState->getAnimationState(name)->setTimePosition(0.0f);
		m_pAnimationMixState->changeAnimation(name,false);

	}
	else if ((mState & ATTACKING_MISS) != 0)
	{
		Ogre::String currentAS = m_pAnimationMixState->getCurrentDestAS()->getAnimationName();
		if(currentAS == "rest")
			return;
		Ogre::String name("rest");
		m_pAnimationMixState->getAnimationState(name)->setTimePosition(0.0f);
		m_pAnimationMixState->changeAnimation(name,true);

	}
	else if ((mState & ATTACKING_SUCCESS) != 0)
	{
		Ogre::String currentAS = m_pAnimationMixState->getCurrentDestAS()->getAnimationName();
		if(currentAS == "cheer01")
			return;
		Ogre::String name("cheer01");
		m_pAnimationMixState->getAnimationState(name)->setTimePosition(0.0f);
		m_pAnimationMixState->changeAnimation(name,true);

	}
	else if ((mState & SHOCKED_BY_LIGHTNING) != 0)
	{
		Ogre::String currentAS = m_pAnimationMixState->getCurrentDestAS()->getAnimationName();
		if(currentAS == "light02")
			return;
		Ogre::String name("light02");
		m_pAnimationMixState->getAnimationState(name)->setTimePosition(0.0f);
		m_pAnimationMixState->changeAnimation(name,true);

	}

}

void Savage::_postload()
{
	Ogre::String matName = m_pEntity->getMesh()->getSubMesh(0)->getMaterialName();
	Ogre::MaterialPtr matPtr= Ogre::MaterialManager::getSingleton().getByName(matName);
	reserved_TextureUnitState = matPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0);
	originalTexture_name = reserved_TextureUnitState->getTextureName();

	Ogre::TextureManager::getSingletonPtr()->load(shockedTexture_name ,"Popular");

}

void Savage::shockedByLightning(Ogre::Real shockTime)
{
	shockTime_process = shockTime;
	mState = SHOCKED_BY_LIGHTNING;

	//change texture to the black one
	reserved_TextureUnitState->setTextureName(shockedTexture_name);

	
}